#include "ClassNode.h"

#include "Output/Console.h"
#include "ScriptCompiler/Token/Token.h"
#include  "ScriptCompiler/AST/AccessLevelNode.h"
#include  "ScriptCompiler/AST/DecoratorNode.h"
#include  "ScriptCompiler/AST/UsingNode.h"
#include  "ScriptCompiler/AST/ClassNode.h"
#include  "ScriptCompiler/AST/DelegateNode.h"
#include  "ScriptCompiler/AST/EnumNode.h"
#include  "ScriptCompiler/AST/FunctionNode.h"
#include  "ScriptCompiler/AST/OperatorFunctionNode.h"
#include  "ScriptCompiler/AST/FieldNode.h"
#include  "ScriptCompiler/AST/PropertyNode.h"
#include  "ScriptCompiler/AST/ParameterNode.h"
#include  "ScriptCompiler/AST/SentenceBlockNode.h"
#include  "ScriptCompiler/AST/ExpressionNode.h"
#include  "ScriptCompiler/AST/NamespaceNode.h"
#include  "ScriptCompiler/AST/ConstructorNode.h"

bool CClassNode::IsClass() const
{
    return Class->Type == EScriptTokenType::Class;
}

bool CClassNode::IsInterface() const
{
    return Class->Type == EScriptTokenType::Interface;
}

bool CClassNode::IsStruct() const
{
    return Class->Type == EScriptTokenType::Struct;
}

void CClassNode::DebugPrint(int32_t InDepth)
{
    //print blank space before access level
    for(int32_t i=0;i<InDepth;++i)
    {
        WH::Print(U"\t");
    }

    if(AccessLevel.HasValue())
    {
        AccessLevel.GetValue()->DebugPrint(0);
    }

    if(Decorator.HasValue())
    {
        Decorator.GetValue()->DebugPrint(0);
    }

    WH::Print(Class->ToString());
    WH::Print(U" ");
    WH::Print(Name->ToString());

    if(GenericPlaceholders.Num()>0)
    {
        WH::Print(U"<");
        for(int32_t i=0;i<GenericPlaceholders.Num();++i)
        {
            WH::Print(GenericPlaceholders[i]->ToString());
            if(i!=GenericPlaceholders.Num()-1)
            {
                WH::Print(U",");
            }
        }
        WH::Print(U">");
    }

    WH::Print(U" ");

    if(!ParentNames.Empty())
    {
        WH::Print(U": ");
        for(auto& ParentName : ParentNames)
        {
            WH::Print(ParentName->ToString());
            WH::Print(U",");
        }
    }

    WH::Print(U"\n");

    //print '{' with depth
    for(int32_t i=0;i<InDepth;++i)
    {
        WH::Print(U"\t");
    }

    WH::Print(U"{\n");

    //print classes
    for(auto& Class : Classes)
    {
        Class->DebugPrint(InDepth+1);
    }

    //print delegates
    for(auto& Delegate : Delegates)
    {
        Delegate->DebugPrint(InDepth+1);
    }

    //print enums
    for(auto& Enum : Enums)
    {
        Enum->DebugPrint(InDepth+1);
    }

    //print constructor
    for(auto& Constructor : Constructors)
    {
        Constructor->DebugPrint(InDepth+1);
    }


    //print functions
    for(auto& Function : Functions)
    {
        Function->DebugPrint(InDepth+1);
    }

    //print operators
    for(auto& Operator : OperatorFunctions)
    {
        Operator->DebugPrint(InDepth+1);
    }

    //print fields
    for(auto& Field : Fields)
    {
        Field->DebugPrint(InDepth+1);
    }

    //print properties
    for(auto& Property : Properties)
    {
        Property->DebugPrint(InDepth+1);
    }


    //print '}' with depth
    for(int32_t i=0;i<InDepth;++i)
    {
        WH::Print(U"\t");
    }

    WH::Print(U"}\n");

}